#include "Qt3DPicker.h"
#include "QDialog"

#include "ArrayHandler.h"
#include "Array2DDialog.h"
#include "Arc2D.h"
#include "CmdManager.h"
#include "Scene.h"
#include "SendPointHandlerBase.h"
#include "SelectHandler3D.h"
#include "OSGNodeMask.h"
#include "Operation/OpAdd.h"
#include "QtOSGWidget.h"
#include "Registry.h"
#include "ActorTable.h"

ArrayHandler::ArrayHandler()
{
	Registry &reg = Registry::instance();
	QWidget * main = reg.get<QWidget>(mainWindowID);
	m_dialog = new Array2DDialog(this, main);
	m_dialog->setButtonEnable(false);
}

ArrayHandler::~ArrayHandler()
{
	delete m_dialog;
}

void ArrayHandler::input(const QVariant& data, const QString& rawInput, CommandSource cs)
{
	m_scene = getScene();
	auto sph = getSendPointHandler();
	auto selector = qobject_cast<SelectHandler3D*>(getSelectHandler());
	if (data.type() == QVariant::Bool)
	{
		bool esc = !data.toBool();
		if (esc)
		{
			selector->clearSelection();
			clearInput();
			clearPreview();
			emit finished();
			return;
		}
	}

	if (status() == 0)
	{
		if (selector)
		{
			selector->clearSelection();
			selector->beginSelect(m_nodeMask);
		}
		else
		{
			emit finished();
		}
		m_dialog->show();
		return;
	}

	if (status() == 1)
	{
		m_origins.clear();
		if (selector && selector->done())
		{
			auto selections = selector->selectionSet();
			if (selections.size() > 0)
			{
				auto selection = *selections.begin();
				std::shared_ptr<Ent> ent = std::dynamic_pointer_cast<Ent>(selection);
				auto parent = ent->getParent();
				if (m_nodeMask == 2)
				{
					UCS* ucs = dynamic_cast<UCS*>(parent);
					if (ucs)
					{
						m_ucs = ucs;
					}
					else
					{
						remark(tr("请选择二维图形"));
						emit finished();
						return;
					}

					for (auto selection : selections)
					{
						std::shared_ptr<Ent2D> ent = std::dynamic_pointer_cast<Ent2D>(selection);
						auto parent = ent->getParent();
						UCS* ucs = dynamic_cast<UCS*>(parent);
						if (ucs != m_ucs)
							continue;
						m_origins.push_back(ent);
					}
				}
				else
				{
					for (auto selection : selections)
					{
						std::shared_ptr<Ent> ent = std::dynamic_pointer_cast<Ent>(selection);
						m_origins.push_back(ent);
					}
				}

				// 按ID排序，确保克隆的时候ID是对应的。
				sort(m_origins.begin(), m_origins.end(), [](const std::shared_ptr<Ent>& e1, const std::shared_ptr<Ent>& e2)
				{
					return e1->getID() < e2->getID();
				});
				if (m_origins.size() > 0)
				{
					m_dialog->setButtonEnable(true);
				}
				else
				{
					m_dialog->setButtonEnable(false);
				}
				m_dialog->show();
			}
			else
			{
				emit finished();
			}
		}
		return;
	}

	// 预览
	if (status() == 2)
	{
		if (data.type() == QVariant::String)
		{
			auto command = data.value<QString>();
			if (command == tr("M") || command == tr("m"))
			{
				//修改
				clearPreview();
				m_dialog->show();
				setStatus(3);
			}
			else
			{
				//接受
				clearPreview();
				auto undoStack = m_scene->undoStack();
				undoStack->push(new OpAdd(arrayEnts));
				selector->clearSelection();
				emit finished();
			}
		}
		return;
	}

	// 确认
	if (status()==4)
	{
		auto undoStack = m_scene->undoStack();
		undoStack->push(new OpAdd(arrayEnts));
		selector->clearSelection();
		emit finished();
	}

	// 取消
	if (status() ==5)
	{
		clearPreview();
		selector->clearSelection();
		emit finished();
	}
}

void ArrayHandler::rectCopy(int rowNumber, double rowDistance, int columnNumber, double columnDistance, float arrayCopyAngle)
{
	arrayEnts.clear();
	int entSize = m_origins.size();
	double angle = M_PI * arrayCopyAngle / 180;
	double x;
	double y;
	auto widget3D = getWidget();
	widget3D->pauseRenderThread();
	for (int index = 0; index < entSize; index++)
	{
		for (int i = 0; i < rowNumber; i++)
		{
			for (int j = 0; j < columnNumber; j++)
			{
				if ((i == 0) && (j == 0))
					continue;
				auto temp = m_origins[index]->clone();
				x = j*columnDistance * cos(angle) - i*rowDistance * sin(angle);
				y = j*columnDistance * sin(angle) + i*rowDistance * cos(angle);
				osg::Vec3d offset = { x,y,0 };
				temp->move(offset);
				if (m_nodeMask == 2)
				{
					m_ucs->addChild(temp);
				}
				else
				{
					m_scene->addChild(temp);
				}
				arrayEnts.insert(temp);
			}
		}
	}
	widget3D->resumeRenderThread();
}

void ArrayHandler::roundCopy(double xCoordinate, double yCoordinate, int totalCount, float angle)
{
	arrayEnts.clear();
	angle = angle * M_PI / 180;
	int entSize = m_origins.size();
	auto widget3D = getWidget();
	widget3D->pauseRenderThread();
	for (int index = 0; index < entSize; index++)
	{
		for (int i = 1; i < totalCount; i++)
		{
			auto temp = std::dynamic_pointer_cast<Ent>(m_origins[index]->clone());
			temp->rotate(angle*i, osg::Vec2d(xCoordinate, yCoordinate));
			if (m_nodeMask == 2)
			{
				m_ucs->addChild(temp);
			}
			else
			{
				m_scene->addChild(temp);
			}
			arrayEnts.insert(temp);
		}
	}
	widget3D->resumeRenderThread();
}

void ArrayHandler::clearPreview()
{
	auto widget3D = getWidget();
	widget3D->pauseRenderThread();
	if (m_nodeMask == 2)
	{
		for (auto temp : arrayEnts)
		{
			m_ucs->removeChild(temp);
		}
	}
	else
	{
		for (auto temp : arrayEnts)
		{
			m_scene->removeChild(temp);
		}
	}
	widget3D->resumeRenderThread();
}
